CloudFormationでSecrets ManagerのプレーンテキストをJSON形式で設定するのにハマった話
こんにちは!AWS事業本部のおつまみです。
先日こちらのブログでTransfer Familyの接続ユーザーをSecretsManagerで管理する方法をお伝えしました。
このブログでは「3. SecretsManagerでシークレットを作成」を手動で行っていました。
ただ、IaC化した方がリソースの管理がしやすいです。
いざやろうと息込んだはいいものの、以下の点にハマってしまいました。
- JSON内で他のスタックからImportValueした文字列をSub関数で結合する必要がある。
- シークレットの値を[キー/値]ではなく、プレーンテキストにJSON形式で設定する必要がある。
そのため今回は私が1時間かけて作成したテンプレートを3分でご紹介します。
いきなり結論
このようなプレーンテキストをSecretManagerで保存します。
{ "Password": "xxxxxxx", "PublicKey": "ssh-rsa xxxxxxx", "Role": "arn:aws:iam::xxxxxxxxxxx:role/test-transferfamily-role", "HomeDirectory": "/fs-xxxxxxxxxxxxx", "SFTPAcceptedIPNetwork": "0.0.0.0", "PosixProfile": { "Uid": "0", "Gid": "0" } }
この場合、CloudFormationテンプレートは下記のようになります。
(ハイライトをかけてる箇所がハマったところです。)
AWSTemplateFormatVersion: '2010-09-09' Description: create SecretsManager # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: Password: Type: String Default: Password PublicKey: Type: String Default: ssh-rsa xxxxxxx SFTPAcceptedIPNetwork: Type: String Default: 0.0.0.0 Resources: SecretManager: Type: "AWS::SecretsManager::Secret" Properties: Name: !Sub - ${TransferServerId}/test-transferfamily-user - TransferServerId: {'Fn::ImportValue': TransferServerId} Description: SFTP Connection for kisyo-server SecretString: !Sub - |- { "Password": "${Password}", "PublicKey": "${PublicKey}", "Role": "${Role}", "HomeDirectory": "/${FileSystemResource}", "SFTPAcceptedIPNetwork": "${SFTPAcceptedIPNetwork}", "PosixProfile": { "Uid": "0", "Gid": "0" } } - {Role: !ImportValue Role} {FileSystemResource: !ImportValue FileSystemResource} Tags: - Key: "Name" Value: !Sub ${PJPrefix}-kisyo-server
※TransferServerId
,Role
,HomeDirectory
は別スタックでOutputしています。
ハマったポイント
このテンプレートを作る際、ハマったポイントをお伝えします。
他のスタックからImportValueした文字列をSub関数で結合する方法
SecretManagerのプレーンテキストは公式ドキュメントの「AWS::SecretsManager::Secret」を見ると、SecretString
にStringで記述する必要があります。
元のプレーンテキストはこのように記載する必要があり、この中でRole
とHomeDirectory
は他のスタックでOutputしています。
{ "Password": "xxxxxxx", "PublicKey": "ssh-rsa xxxxxxx", "Role": "arn:aws:iam::xxxxxxxxxxx:role/test-transferfamily-role", "HomeDirectory": "/fs-xxxxxxxxxxxxx", "SFTPAcceptedIPNetwork": "0.0.0.0", "PosixProfile": { "Uid": "0", "Gid": "0" } }
そのため、ImportValueした文字列をSub関数で結合する必要があります。
公式ドキュメントの「組み込み関数リファレンス » Fn::Sub」を見ると、実行時に取得する値(以下の Var1Value、Var2Value )を Sub 関数のパラメータに含むことができると書かれています。
短縮形の構文:
!Sub - String - { Var1Name: Var1Value, Var2Name: Var2Value }
ここでString
は、"${VarName}"
のように実行時に取得する値と置き換えることができます。
よって、ImportValueした文字列をSub関数で結合する場合、下記のように記述する必要があります。
!Sub - "${Role}", - {Role: !ImportValue Role}
YAML記述のCloudFormation内でJSONを埋め込む方法
次にSecretManagerのプレーンテキストはJSON形式で記述しなければいけません。
そのため、YAML記述のCloudFormation内にどう置換すればいいのか悩みました。
ググったところ、こちらのブログに記述方法が載ってました。(ありがたや)
よってSecretManagerのプレーンテキストはこのように記述することができます。
SecretString: !Sub - |- { "Password": "${Password}", "PublicKey": "${PublicKey}", "Role": "${Role}", "HomeDirectory": "/${EFSID}", "SFTPAcceptedIPNetwork": "${SFTPAcceptedIPNetwork}", "PosixProfile": { "Uid": "0", "Gid": "0" } } - {Role: !ImportValue Role} {EFSID: !ImportValue FileSystemResource}
こちらCloudFormationで実行してみます。
想定通りJSON形式で保存できました!
最後に
今回はCloudFormationでSecrets ManagerのプレーンテキストをJSON形式で設定するのにハマった話をお伝えしました。
CloudFormationの組み込み関数は奥深いなと思いました。
だんだん慣れていけるようになりたいです。
最後までお読みいただきありがとうございました!
どなたかのお役に立てれば幸いです。
以上、おつまみ(@AWS11077)でした!